/******************************************************************************中
 * @brief: eth task
 * @Author: aple
 * @Date: 2022-12-14 12:37:50
 * @LastEditors: aple
 * @LastEditTime: 2022-12-14 12:41:45
 * @Verision: 1.0.0.0
 ******************************************************************************/
#include "framework.h"
#include "core/net.h"
#include "modbus/modbus_server.h"
#include "eth_task.h"
#include "lib_surport.h"

/*******************************************************************************
 * @brief: modbus config default
 ******************************************************************************/
error_t emb_ModbusServerOpenCallback(ModbusClientConnection *connection, IpAddr clientIpAddr, uint16_t clientPort);
void emb_ModbusServerCloseCallback(ModbusClientConnection *connection);
void emb_ModbusServerLockCallback(ModbusClientConnection *connection);
void emb_ModbusServerUnlockCallback(ModbusClientConnection *connection);
error_t emb_ModbusServerReadDiscreteInputCallback(
    ModbusClientConnection *connection,
    uint16_t address, bool_t *state);
error_t emb_ModbusServerReadCoilCallback(
    ModbusClientConnection *connection,
    uint16_t address, bool_t *state);
error_t emb_ModbusServerWriteCoilCallback(
    ModbusClientConnection *connection,
    uint16_t address, bool_t state, bool_t commit);
error_t emb_ModbusServerReadRegCallback(
    ModbusClientConnection *connection,
    uint16_t address, uint16_t *value);
error_t emb_ModbusServerReadHoldingRegCallback(
    ModbusClientConnection *connection,
    uint16_t address, uint16_t *value);
error_t emb_ModbusServerReadInputRegCallback(
    ModbusClientConnection *connection,
    uint16_t address, uint16_t *value);
error_t emb_ModbusServerWriteRegCallback(
    ModbusClientConnection *connection,
    uint16_t address, uint16_t value, bool_t commit);
error_t emb_ModbusServerProcessPduCallback(
    ModbusClientConnection *connection,
    const uint8_t *request, size_t requestLen, uint8_t *response,
    size_t *responseLen);
void emb_ModbusServerTickCallback(ModbusServerContext *context);

const ModbusServerSettings emb_server_cfg_default = {
    .openCallback = emb_ModbusServerOpenCallback,
    .closeCallback = emb_ModbusServerCloseCallback,
    .lockCallback = emb_ModbusServerLockCallback,
    .unlockCallback = emb_ModbusServerUnlockCallback,
    .readCoilCallback = emb_ModbusServerReadCoilCallback,
    .readDiscreteInputCallback = emb_ModbusServerReadDiscreteInputCallback,
    .writeCoilCallback = emb_ModbusServerWriteCoilCallback,
    .readRegCallback = emb_ModbusServerReadRegCallback,
    .readInputRegCallback = emb_ModbusServerReadInputRegCallback,
    .readHoldingRegCallback = emb_ModbusServerReadHoldingRegCallback,
    .writeRegCallback = emb_ModbusServerWriteRegCallback,
    .processPduCallback = 0, // 用于调试数据包
    .tickCallback = emb_ModbusServerTickCallback,
};

/*******************************************************************************
 * @brief: var
 ******************************************************************************/
ModbusServerContext emb_server_context;

/*******************************************************************************
 * @brief: eth modbus init
 * @param void
 * @return {*}
 ******************************************************************************/
void emb_server_init(void)
{
    ModbusServerSettings emb_cfg;

    memcpy(&emb_cfg, &emb_server_cfg_default, sizeof(emb_cfg));

    emb_cfg.task.priority = osPriorityNormal;
    emb_cfg.task.stackSize = 512;
    emb_cfg.interface = &netInterface[0];
    emb_cfg.port = 502;
    emb_cfg.unitId = 3;
    emb_cfg.timeout = 60000;

    modbusServerInit(&emb_server_context, &emb_cfg);

    modbusServerStart(&emb_server_context);
}

/*******************************************************************************
 * @brief: eth modbus deinit
 * @param void
 * @return {*}
 ******************************************************************************/
void emb_server_deinit(void)
{
    modbusServerStop(&emb_server_context);
    modbusServerDeinit(&emb_server_context);
	// 需手动删除OS任务和OS事件
	osDeleteEvent(&emb_server_context.event);
	osDeleteTask(emb_server_context.taskId);
}

/**
 * @brief TCP connection open callback function
 **/

error_t emb_ModbusServerOpenCallback(ModbusClientConnection *connection, IpAddr clientIpAddr, uint16_t clientPort)
{
    return 0;
}

/**
 * @brief TCP connection close callback function
 **/
void emb_ModbusServerCloseCallback(ModbusClientConnection *connection)
{
}

/**
 * @brief Lock Modbus table callback function
 **/

void emb_ModbusServerLockCallback(ModbusClientConnection *connection)
{
}

/**
 * @brief Unlock Modbus table callback function
 **/

void emb_ModbusServerUnlockCallback(ModbusClientConnection *connection)
{
}

/**
 * @brief Get DiscreteInput state callback function
 **/

error_t emb_ModbusServerReadDiscreteInputCallback(
    ModbusClientConnection *connection,
    uint16_t address, bool_t *state)
{
    return 0;
}

/**
 * @brief Get coil state callback function
 **/

error_t emb_ModbusServerReadCoilCallback(
    ModbusClientConnection *connection,
    uint16_t address, bool_t *state)
{
    return 0;
}

/**
 * @brief Set coil state callback function
 **/

error_t emb_ModbusServerWriteCoilCallback(
    ModbusClientConnection *connection,
    uint16_t address, bool_t state, bool_t commit)
{
    return 0;
}

/**
 * @brief Get register value callback function
 **/

error_t emb_ModbusServerReadRegCallback(
    ModbusClientConnection *connection,
    uint16_t address, uint16_t *value)
{
    *value = 33;
    return 0;
}

/**
 * @brief Get register value callback function
 **/

error_t emb_ModbusServerReadHoldingRegCallback(
    ModbusClientConnection *connection,
    uint16_t address, uint16_t *value)
{
    *value = (lib_tick32_cnt >> 10) + address;
    return 0;
}

/**
 * @brief Get register value callback function
 **/

error_t emb_ModbusServerReadInputRegCallback(
    ModbusClientConnection *connection,
    uint16_t address, uint16_t *value)
{
    *value = 55;
    return 0;
}

/**
 * @brief Set register value callback function
 **/

error_t emb_ModbusServerWriteRegCallback(
    ModbusClientConnection *connection,
    uint16_t address, uint16_t value, bool_t commit)
{
    return 0;
}

/**
 * @brief PDU processing callback function
 **/
error_t emb_ModbusServerProcessPduCallback(
    ModbusClientConnection *connection,
    const uint8_t *request, size_t requestLen, uint8_t *response,
    size_t *responseLen)
{

    // response =    request;
    // *responseLen = requestLen;
    return 0;
}

/**
 * @brief Tick callback function
 **/

void emb_ModbusServerTickCallback(ModbusServerContext *context)
{
}
